/*
    原文链接：http://www.cnblogs.com/lianmin/p/5940637.html
    本人只是copy别人的学习，并未写出什么新的
*/

;(function($){
    /*缓动函数*/
    $.extend($.easing, {
        easeOutElastic: function (x, t, b, c, d) {
            var s = 1.70158; var p = 0; var a = c;
            if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3;
            if (a < Math.abs(c)) { a = c; var s = p / 4; }
            else var s = p / (2 * Math.PI) * Math.asin(c / a);
            return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
        }
    });

    $.fn.qin = function(option){
        var defaults = {
            maxVal: 25,  // 最大偏移量
            duration: 500,  // 晃动时间
            recline: 0.1 // 每像素偏移量
        }

        var opt = $.extend({}, defaults, option);

        return $(this).each(function(){
            var $ele = $(this);
            fillSpan($ele);
            addQin($ele, opt);
        })
    }

    function fillSpan($ele){
        //插入span
        var str = '';
        var html = $ele.html();
        for(var i = 0; i < html.length; i++){
            str += '<span>' + html[i] + '</span>'
        };
        $ele.html(str);
        
        //计算位置
        var positionArr = []; //存放初始位置；
        $ele.children('span').each(function(index){

            var $span = $(this);
            var position = $span.position();
            positionArr.push(position);

            $span.css({
                'left':position.left,
                'top':position.top,
            });

            //这里必须在延迟之后设置
            setTimeout(function(){
                $span.css({
                    'position':'absolute'
                });
            });
        });
        //储存初始对象
        $ele.data('positionArr',positionArr);

    }

    function addQin($ele, opt){
        var positionArr = $ele.data('positionArr'); //原始位置
        
        var startX = 0; //初始x轴位置
        var startY = 0; //初始y轴位置

        $ele.on('mouseenter',function(e){
            var offset = $ele.offset();

            startX = e.pageX - offset.left; //鼠标在元素内x轴的位置
            startY = e.pageY - offset.top;  //鼠标在元素内y轴的位置
        });

        $ele.on('mousemove',function(e){
            var offset = $ele.offset();

            var endX = e.pageX - offset.left;    //鼠标在元素内x轴的位置
            var endY = e.pageY - offset.top;     //鼠标在元素内y轴的位置

            var reY = endY - startY;    //y轴移动距离
            
            if(Math.abs(reY) > opt.maxVal){ //大于最大偏移值直接退出
                return;
            }

            //方向
            var ifDown = reY > 0; //true向下，反之
            
            $ele.children('span').each(function(index){
                var $span = $(this);
                var position = positionArr[index];  //初始位置
                var num = Math.abs(endX - position.left) * opt.recline; // Y 轴移动距离，基于原始位置
                num *= ifDown ? 1 : (-1);    //向下还是向上

                var valY = position.top + reY - num;
                if (ifDown && valY < position.top) {
                    valY = position.top;
                }
                else if (!ifDown && valY > position.top) {
                    valY = position.top;
                }
                
                $span.css({
                    'top':valY + 'px'
                });
            })
        });
        
        $ele.on('mouseleave',function(){
            $(this).find('span').each(function(index){
                var $span = $(this);
                //还原位置
                $span.animate({
                    top:positionArr[index].top + 'px'
                },{
                    duration:opt.duration,
                    easing:'easeOutElastic'
                });
            });
        });
    }
})(jQuery);